package com.boarsoft.boar.gateway.weixin.service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.boarsoft.boar.gateway.wechat.common.WechatConfig;
import com.boarsoft.boar.gateway.wechat.common.WechatConstance;
import com.boarsoft.boar.gateway.weixin.biz.WxUserBiz;
import com.boarsoft.boar.gateway.weixin.common.WeixinFactory;
import com.boarsoft.boar.gateway.weixin.common.WeixinPlatformUser;
import com.boarsoft.boar.gateway.weixin.common.WxFormatData;
import com.boarsoft.boar.gateway.weixin.entity.WxBinding;
import com.boarsoft.cache.Cache;
import com.boarsoft.wechat.entity.WeChatTemplate;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

/**
 * 微信动账提示抽象类
 * 
 * @author huanglong
 *
 */
public abstract class WxQmsgService{

	protected Logger log = LoggerFactory.getLogger(WxQmsgService.class);
	
	public abstract Cache getCache();
	
	public abstract WxUserBiz getWxUserBiz();
	
	/**
	 * 循环发送微信提示消息
	 * 
	 * @param list 微信提示消息
	 * @return
	 * @throws Exception
	 */
	protected Map<String, Object> sendMessage(List<Map<String, Object>> list) throws Exception{
		log.info("sendMessage start");
		Long sTime = new Date().getTime();
		Map<String, Object> reMap = new HashMap<String, Object>();
		reMap.put("respCode", "0000000000");
		reMap.put("respMsg", "成功");
		if(list == null || list.size() == 0){
			reMap.put("successNum", 0);
		}else{
			int successNum = 0;
			String fakeId = WechatConfig.getProperty("weixin.platformFakeId");
			for (Map<String, Object> map : list) {
				log.info("sendMessage one start|{}|{}", fakeId, new Gson().toJson(map));
				Long s1Time = new Date().getTime();
				Map<String, Object> msgMap = dealMessage(fakeId, map);
				if("0000000000".equals(msgMap.get("respCode"))){
					successNum ++;
				}
				Long e1Time = new Date().getTime();
				log.info("sendMessage one end|{}|{}", e1Time - s1Time, new Gson().toJson(msgMap));
			}
			reMap.put("successNum", successNum);
		}
		Long eTime = new Date().getTime();
		log.info("sendMessage end|{}|{}", eTime - sTime, new Gson().toJson(reMap));
		return reMap;
	}
	
	/**
	 * 校验数据是推送微信公众号
	 * 
	 * @param fakeId 微信公众号fakeId
	 * @param msgDataMap 提示数据
	 * @return
	 */
	protected Map<String, Object> dealMessage(String fakeId, Map<String, Object> msgDataMap){
		Map<String, Object> reMap = new HashMap<String, Object>();
		String tempCode = (String)msgDataMap.get("TEMPCODE");
		Object tranCodeObj = msgDataMap.get("TRANCODE");
		
		//检查模板是否存在
		WeChatTemplate template;
		try {
			//则默认按照“<TEMPCODE>_<TRANSCODE>”取对应的模板进行报文解析，如果对应“<TRANSCODE>”的无模板，则取模板“<TEMPCODE>”进行解析。
			if(tranCodeObj != null && !"".equals((String)tranCodeObj)){
				Object tempCodeObj = this.getCache().get(WechatConstance.TEMPLET_TYPE_CACHE_NAME, tempCode + "_" + (String)tranCodeObj);
				if(tempCodeObj != null){
					tempCode = (String)tempCodeObj;
				}
			}
			
			Object tempObj = this.getCache().get(WechatConstance.TEMPLET_CACHE_NAME, tempCode);
			if(tempObj == null){
				log.info("微信模板不存在{}", tempCode);
				reMap.put("respCode", "EBWX010001");
				reMap.put("respMsg", "微信模板不存在");
				return reMap;
			}
			template = (WeChatTemplate)tempObj;
		
			//检查账户是否绑定微信
			String acctKey = template.getSendAccKey();
			String acctNo = (String)msgDataMap.get(acctKey);
			WxBinding user = this.getWxUserBiz().getByAcctNo(fakeId, acctNo);
			if(user == null){
				log.info("账号在微信没有绑定{}", acctNo);
				reMap.put("respCode", "EBWX010002");
				reMap.put("respMsg", "该账号没有在微信公众平台绑定");
				return reMap;
			}
			
			WeixinPlatformUser platformUser =  WeixinFactory.getWeixinPlatformUser(fakeId);
			if("true".equals(WechatConfig.getProperty("weixin.testFlag"))){
				String sendData = formatMsgStr(user, msgDataMap, template);
				reMap.put("respCode", "0000000000");
				reMap.put("respMsg", "微信发送成功");
				reMap.put("sendData", sendData);
			}else{
				reMap = platformUser.sendTemplateMsg(formatMsgStr(user, msgDataMap, template));
			}
		} catch (Exception e) {
			log.error("微信模板解析出错", e);
			reMap.put("respCode", "EBWX010003");
			reMap.put("respMsg", "微信模板解析出错");
			return reMap;
		}
		return reMap;
	}
	
	/**
	 * 解析数据
	 * 
	 * @param user 微信用户
	 * @param msgDataMap 消息数据
	 * @param template 消息模板
	 * @return
	 */
	private String formatMsgStr(WxBinding user, Map<String, Object> msgDataMap, WeChatTemplate template){
		
		StringBuffer sb = new StringBuffer();
		//微信用户
		sb.append("{\"touser\":\"" + user.getFakeId() + "\"");
		//微信模板id
		sb.append(",\"template_id\":\"" + template.getTemplateId() + "\"");
		//微信消息提示跳转连接
		if(template.getUrl()!=null && !"".equals(template.getUrl())){
			sb.append(",\"url\":\"" + template.getUrl() + "\"");
		}
		//微信消息提示app跳转连接
		if(template.getMiniProgramAppId()!=null && !"".equals(template.getMiniProgramAppId())  
				&& template.getMiniProgramPagePath()!=null && !"".equals(template.getMiniProgramPagePath()) ){
			sb.append(",\"miniprogram\":{");
			sb.append("\"appid\":\"" + template.getMiniProgramAppId() + "\"");
			sb.append(",\"pagepath\":\"" + template.getMiniProgramPagePath() + "\"");
			sb.append("}");
		}
		//微信消息提示 模板数据
		if(template.getDataKey()!=null && !"".equals(template.getDataKey())){
			sb.append(",\"data\":{");
			Gson gson = new Gson();
			//数据解析方式{"tempkey":"valuekey||01"} tempkey为填充模板数据的key，valuekey为获取数据的key，01为数据转换规则
			Map<String, String> ruleMap = gson.fromJson(template.getDataRule(), new TypeToken<Map<String, String>>(){}.getType());
			String dataKey = template.getDataKey();
			for (Map.Entry<String, String> entry : ruleMap.entrySet()) {
				String key = entry.getKey();
				String[] rule = entry.getValue().split("\\|\\|");
				String value = WxFormatData.formatData(rule[0], rule[1], msgDataMap);
				dataKey = dataKey.replaceAll("\\$\\{" + key + "\\}", value);
			}
			
			//数据模板
			Map<String, String> dataKeyMap = gson.fromJson(dataKey, new TypeToken<Map<String, String>>(){}.getType());
			//数据显示颜色
			Map<String, String> colorMap = new HashMap<String, String>();
			if(template.getDataColor()!=null && !"".equals(template.getDataColor())){
				colorMap = gson.fromJson(template.getDataColor(), new TypeToken<Map<String, String>>(){}.getType());
			}
			int i = 0;
			for (Map.Entry<String, String> entry : dataKeyMap.entrySet()) {
				String key = entry.getKey();
				String value = entry.getValue();
				String color = colorMap.get(key);
				if(i!=0)sb.append(",");
				sb.append("\"" + key + "\":{");
				sb.append("\"value\":\"" + value + "\"");
				if(color!=null && !"".equals(color)){
					sb.append(",\"color\":\"" + color + "\"");
				}
				sb.append("}");
				i++;
			}
			sb.append("}");
		}
		sb.append("}");
		return sb.toString();
	}
}
